package com.dpwgc.pan.controller;

import java.util.List;
import java.util.Map;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.fs.BlockLocation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.dpwgc.pan.service.HdfsService;
import com.dpwgc.pan.utils.ResultUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * HDFS文件操作
 */
@CrossOrigin
@RestController
@Api("HDFS文件操作")
@RequestMapping("/Hdfs")
public class HdfsController {

    @Autowired
    HdfsService hdfsService;

    /**
     * 创建文件夹
     * @param path 文件夹所在目录
     * @return
     * @throws Exception
     */
    @ApiOperation("创建文件夹")
    @RequestMapping(value = "/mkdir", method = RequestMethod.POST)
    public ResultUtil<Object> mkdir(@RequestParam("path") String path) throws Exception {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        if (StringUtils.isEmpty(path)) {

            resultUtil.setCode(100);
            resultUtil.setMsg("路径不能为空");
            return resultUtil;
        }

        if (path.length()<10) {

            resultUtil.setCode(100);
            resultUtil.setMsg("错误路径");
            return resultUtil;
        }
        // 创建空文件夹
        boolean flag = hdfsService.mkdirService(path);
        if (flag) {
            resultUtil.setCode(200);
            resultUtil.setMsg("文件夹创建成功");
            return resultUtil;
        } else {
            resultUtil.setCode(100);
            resultUtil.setMsg("文件夹创建失败");
            return resultUtil;
        }
    }

    /**
     * 读取当前目录信息
     * @param path 文件夹路径
     * @return
     * @throws Exception
     */
    @ApiOperation("读取当前目录信息")
    @RequestMapping(value = "/readPathInfo", method = RequestMethod.POST)
    public ResultUtil<Object> readPathInfo(@RequestParam("path") String path) throws Exception {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        if (StringUtils.isEmpty(path)) {

            resultUtil.setCode(100);
            resultUtil.setMsg("路径不能为空");
            return resultUtil;
        }

        if (path.length()<10) {

            resultUtil.setCode(100);
            resultUtil.setMsg("错误路径");
            return resultUtil;
        }

        List<Map<String, Object>> list = hdfsService.readPathInfoService(path);

        resultUtil.setCode(200);
        resultUtil.setMsg("获取成功");
        resultUtil.setData(list);
        return resultUtil;
    }

    /**
     * 获取文件在集群中的位置
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    @ApiOperation("获取HDFS文件在集群中的位置")
    @RequestMapping(value = "/getFileBlockLocations", method = RequestMethod.POST)
    public ResultUtil<Object> getFileBlockLocations(@RequestParam("path") String path) throws Exception {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        BlockLocation[] blockLocations = hdfsService.getFileBlockLocationsService(path);

        resultUtil.setCode(200);
        resultUtil.setMsg("获取成功");
        resultUtil.setData(blockLocations);
        return resultUtil;
    }

    /**
     * 文件上传
     * @param path 文件保存路径
     * @param file 文件
     * @return
     * @throws Exception
     */
    @ApiOperation("文件上传")
    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    public ResultUtil<Object> uploadFile(@RequestParam("path") String path,@RequestParam("file") MultipartFile file) throws Exception {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        if (StringUtils.isEmpty(path) || null == file.getBytes()) {
            resultUtil.setCode(100);
            resultUtil.setMsg("存储路径或文件数据不能为空");
            return resultUtil;
        }

        boolean flag = hdfsService.uploadFileService(path, file);

        if(flag){
            resultUtil.setCode(200);
            resultUtil.setMsg("文件上传成功");
            return resultUtil;
        }else {
            resultUtil.setCode(100);
            resultUtil.setMsg("文件上传失败");
            return resultUtil;
        }
    }

    /**
     * 读取文件内容
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    @ApiOperation("读取文件内容")
    @RequestMapping(value = "/readFile", method = RequestMethod.POST)
    public ResultUtil<Object> readFile(@RequestParam("path") String path) {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        String fileData;

        try{
            fileData = hdfsService.readFileService(path);
            resultUtil.setCode(200);
            resultUtil.setMsg("获取成功");
            resultUtil.setData(fileData);
            return resultUtil;

        }catch (Exception e){

            resultUtil.setCode(100);
            resultUtil.setMsg("获取失败");
            resultUtil.setData(e);
            return resultUtil;
        }
    }

    /**
     * 文件下载（GET请求）
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    @ApiOperation("文件下载（返回字符流数据给前端）")
    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
    public void downloadFile(@RequestParam("path") String path,HttpServletRequest request, HttpServletResponse response) throws Exception {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        hdfsService.downloadFileService(path,request,response);
    }

    /**
     * 获取该目录下的所有文件信息
     * @param path 文件夹路径
     * @return
     * @throws Exception
     */
    @ApiOperation("读取文件夹下的文件列表")
    @RequestMapping(value = "/listFile", method = RequestMethod.POST)
    public ResultUtil<Object> listFile(@RequestParam("path") String path) throws Exception {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        if (StringUtils.isEmpty(path)) {

            resultUtil.setCode(100);
            resultUtil.setMsg("路径不能为空");
            return resultUtil;
        }
        List<Map<String, String>> returnList = hdfsService.listFileService(path);

        resultUtil.setCode(200);
        resultUtil.setMsg("获取成功");
        resultUtil.setData(returnList);
        return resultUtil;
    }

    /**
     * 重命名文件
     * @param oldPath 旧文件路径
     * @param newPath 新文件路径
     * @return
     * @throws Exception
     */
    @ApiOperation("重命名文件")
    @RequestMapping(value = "/renameFile", method = RequestMethod.POST)
    public ResultUtil<Object> renameFile(@RequestParam("oldPath") String oldPath,
                                         @RequestParam("newPath") String newPath) throws Exception {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        if (StringUtils.isEmpty(oldPath)) {
            resultUtil.setCode(100);
            resultUtil.setMsg("未选择文件");
            return resultUtil;
        }
        if (StringUtils.isEmpty(newPath)) {
            resultUtil.setCode(100);
            resultUtil.setMsg("文件名不能为空");
            return resultUtil;
        }

        boolean flag = hdfsService.renameFileService(oldPath, newPath);

        if (flag) {
            resultUtil.setCode(200);
            resultUtil.setMsg("操作成功");
            return resultUtil;
        } else {
            resultUtil.setCode(200);
            resultUtil.setMsg("操作失败");
            return resultUtil;
        }
    }

    /**
     * 删除文件
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    @ApiOperation("删除文件")
    @RequestMapping(value = "/deleteFile", method = RequestMethod.POST)
    public ResultUtil<Object> deleteFile(@RequestParam("path") String path) {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        try{

            boolean flag = hdfsService.deleteFileService(path);

            if (flag) {

                resultUtil.setCode(200);
                resultUtil.setMsg("操作成功");
                return resultUtil;

            } else {

                resultUtil.setCode(100);
                resultUtil.setMsg("操作失败");
                return resultUtil;
            }

        }catch (Exception e){

            resultUtil.setCode(100);
            resultUtil.setMsg("操作失败");
            resultUtil.setData(e);
            return resultUtil;
        }
    }

    /**
     * 复制文件
     * @param sourcePath 原文件路径
     * @param targetPath 目标文件路径
     * @return
     * @throws Exception
     */
    @ApiOperation("复制文件")
    @RequestMapping(value = "/copyFile", method = RequestMethod.POST)
    public ResultUtil<Object> copyFile(@RequestParam("sourcePath") String sourcePath,
                                       @RequestParam("targetPath") String targetPath) {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        if (StringUtils.isEmpty(sourcePath) || StringUtils.isEmpty(targetPath)) {

            resultUtil.setCode(100);
            resultUtil.setMsg("路径不能为空");
            return resultUtil;
        }

        try {
            hdfsService.copyFileService(sourcePath, targetPath);

            resultUtil.setCode(200);
            resultUtil.setMsg("复制成功");
            return resultUtil;

        }catch (Exception e){

            resultUtil.setCode(100);
            resultUtil.setMsg("复制失败");
            return resultUtil;
        }
    }

    /**
     * 获取该目录下的文件总数及总大小
     * @param path 文件夹路径
     * @return
     * @throws Exception
     */
    @ApiOperation("读取文件夹下的文件列表")
    @RequestMapping(value = "/countFile", method = RequestMethod.POST)
    public ResultUtil<Object> countFile(@RequestParam("path") String path,
                                        @RequestParam("userId") int userId) throws Exception {

        ResultUtil<Object> resultUtil = new ResultUtil<>();

        if (StringUtils.isEmpty(path)) {

            resultUtil.setCode(100);
            resultUtil.setMsg("路径不能为空");
            return resultUtil;
        }
        Map<String,Object> map = hdfsService.countFileService(path,userId);

        resultUtil.setCode(200);
        resultUtil.setMsg("获取成功");
        resultUtil.setData(map);
        return resultUtil;
    }
}